#include "wind_direction.h"
#include "iot_uart.h"
#include "los_task.h"
#include "ohos_init.h"
#include "iot_errno.h"

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#define WIND_UART_ID EUART0_M0
#define WIND_UART_BAUDRATE 4800
#define WIND_TASK_STACK 2048
#define WIND_TASK_PRIO 25

#define MODBUS_ADDR 0x01
#define MODBUS_FUNC_READ 0x03
#define WIND_REG_ADDR 0x0000
#define WIND_REG_COUNT 0x0002

static uint16_t modbus_crc16(const uint8_t *data, uint16_t len)
{
    uint16_t crc = 0xFFFF;
    for (uint16_t i = 0; i < len; i++)
    {
        crc ^= data[i];
        for (int j = 0; j < 8; j++)
        {
            if (crc & 0x0001)
                crc = (crc >> 1) ^ 0xA001;
            else
                crc >>= 1;
        }
    }
    return crc;
}

static const char *GetWindDirectionName(float degree)
{
    // 八方位
    if (degree >= 337.5 || degree < 22.5)
    {
        return "北";
    }
    else if (degree >= 22.5 && degree < 67.5)
    {
        return "东北";
    }
    else if (degree >= 67.5 && degree < 112.5)
    {
        return "东";
    }
    else if (degree >= 112.5 && degree < 157.5)
    {
        return "东南";
    }
    else if (degree >= 157.5 && degree < 202.5)
    {
        return "南";
    }
    else if (degree >= 202.5 && degree < 247.5)
    {
        return "西南";
    }
    else if (degree >= 247.5 && degree < 292.5)
    {
        return "西";
    }
    else
    {
        return "西北";
    }
}	

static float wind_direction_task()
{
    IoTUartDeinit(WIND_UART_ID); // 防止占用，重新初始化

    IotUartAttribute attr = {
        .baudRate = WIND_UART_BAUDRATE,
        .dataBits = IOT_UART_DATA_BIT_8,
        .parity = IOT_UART_PARITY_NONE,
        .stopBits = IOT_UART_STOP_BIT_1,
        .rxBlock = IOT_UART_BLOCK_STATE_BLOCK,
        .txBlock = IOT_UART_BLOCK_STATE_BLOCK,
        .pad = IOT_FLOW_CTRL_NONE,
    };

    if (IoTUartInit(WIND_UART_ID, &attr) != IOT_SUCCESS)
    {
        printf("[WIND] Failed to init UART%d\n", WIND_UART_ID);
        return;
    }

    
        uint8_t tx_buf[8] = {0};
        uint8_t rx_buf[16] = {0};

        tx_buf[0] = MODBUS_ADDR;
        tx_buf[1] = MODBUS_FUNC_READ;
        tx_buf[2] = (WIND_REG_ADDR >> 8) & 0xFF;
        tx_buf[3] = WIND_REG_ADDR & 0xFF;
        tx_buf[4] = (WIND_REG_COUNT >> 8) & 0xFF;
        tx_buf[5] = WIND_REG_COUNT & 0xFF;

        uint16_t crc = modbus_crc16(tx_buf, 6);
        tx_buf[6] = crc & 0xFF;        // CRC低位
        tx_buf[7] = (crc >> 8) & 0xFF; // CRC高位

        int ret = IoTUartWrite(WIND_UART_ID, tx_buf, 8);
        if (ret <= 0)
        {
            printf("[WIND] UART write failed\n");
            goto next;
        }

        usleep(100000); // 延迟等待数据返回

        ret = IoTUartRead(WIND_UART_ID, rx_buf, sizeof(rx_buf));
        if (ret < 7)
        {
            printf("[WIND] UART read failed or not enough data (ret=%d)\n", ret);
            goto next;
        }

        printf("[WIND] Received %d bytes:\n", ret);
        for (int i = 0; i < ret; i++)
        {
            printf("%02X ", rx_buf[i]);
        }
        printf("\n");

        if (rx_buf[0] != MODBUS_ADDR || rx_buf[1] != MODBUS_FUNC_READ || rx_buf[2] != 2)
        {
            printf("[WIND] Invalid response header\n");
            goto next;
        }

        uint16_t wind_val = (rx_buf[3] << 8) | rx_buf[4];
        float wind_degree = wind_val * 22.5f;

        const char *wind_dir_name = GetWindDirectionName(wind_degree);
        return wind_degree;
//        printf("[WIND] Direction: %.1f° (%s)\n", wind_degree, wind_dir_name);

//    next:
//        usleep(2000000); // 每2秒读取一次
//    
}

void wind_direction_init(void)
{
    TSK_INIT_PARAM_S task = {
        .pfnTaskEntry = (TSK_ENTRY_FUNC)wind_direction_task,
        .uwStackSize = WIND_TASK_STACK,
        .pcName = "wind_direction",
        .usTaskPrio = WIND_TASK_PRIO,
    };
    unsigned int tid;
    if (LOS_TaskCreate(&tid, &task) != LOS_OK)
    {
        printf("[WIND] Failed to create wind direction task\n");
    }
}
